/*
	weak_type_detail.hpp
	Most of the implementation details here
	@author:Wolfhead
*/
#ifndef WOLV_WEAK_TYPE_DETAIL
#define WOLV_WEAK_TYPE_DETAIL

#include <map>
#include <vector>
#include <string>
#include <new>
#include "weak_type_define.h"


namespace wolv
{
namespace weakType
{
namespace _detail
{

// data holder
typedef union _tag_dataHolder
{
	int int_value;
	bool bool_value;
	double double_value;
	char string_value[sizeof(string_type)];
	char array_value[sizeof(array_type)];
	char object_value[sizeof(object_type)];
}_dataHolder;

// data pointer
typedef union _tag_dataHolder_ptr
{
	int * int_;
	bool* bool_;
	double* double_;
	string_type* string_;
	array_type* vec_;
	object_type* map_;
}_dataHolder_ptr;

// data reference
typedef struct _tag_dataHolder_ref
{
	_tag_dataHolder_ref(_tag_dataHolder_ptr ptr):
		int_value(*ptr.int_),
		bool_value(*ptr.bool_),
		double_value(*ptr.double_),
		string_value(*ptr.string_),
		array_value(*ptr.vec_),
		object_value(*ptr.map_)
	{

	}
	int& int_value;
	bool& bool_value;
	double& double_value;
	string_type& string_value;
	array_type& array_value;
	object_type& object_value;
}_dataHolder_ref;


inline _tag_dataHolder_ptr data2ptr(void * ptr)
{
	union
	{
		void* from;
		_tag_dataHolder_ptr to;
	} cast;

	cast.from = ptr;
	return cast.to;
}

inline _tag_dataHolder_ref data2ref(void * ptr)
{
	return data2ptr(ptr);
}


template<typename T>
inline void ___destroy(T* value)
{
	value->~T();
}

template<typename T>
inline void ___alloc(T* place)
{
	new (place) T();
}

template<typename T>
inline void ___alloc(T* place, const T& _value)
{
	new (place) T(_value);
}

inline void __destroyDataHolder(valueType type, _dataHolder_ref data)
{
	switch (type) 
	{
	case intType:
	case boolType:
	case doubleType:
		return;

	case stringType:
		___destroy(&data.string_value);
		return;
	case arrayType:
		___destroy(&data.array_value);
		return;
	case objectType:
		___destroy(&data.object_value);
		return;
	default:
		return;
	}
}

inline void __allocDataHolder(valueType type, _dataHolder_ref data)
{
	switch (type) 
	{
	case intType:
	case boolType:
	case doubleType:
		return;

	case stringType:
		___alloc(&data.string_value);
		return;
	case arrayType:
		___alloc(&data.array_value);
		return;
	case objectType:
		___alloc(&data.object_value);
		return;
	default:
		return;
	}
}

inline void __allocDataHolder(valueType type, _dataHolder_ref data, _dataHolder_ref _data)
{
	switch (type) 
	{
	case intType:
		data.int_value = _data.int_value;
		return;
	case boolType:
		data.bool_value = _data.bool_value;
		return;
	case doubleType:
		data.double_value = _data.double_value;
		return;
	case stringType:
		___alloc(&data.string_value, _data.string_value);
		return;
	case arrayType:
		___alloc(&data.array_value, _data.array_value);
		return;
	case objectType:
		___alloc(&data.object_value, _data.object_value);
		return;
	default:
		return;
	}
}

static char SIGN_ARRAY[256] =
{
	//      0 1 2 3 4 5 6 7 8 9 A B C D E F
	/* 0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 2 */ 0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,
	/* 3 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 4 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 7 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 8 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 9 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* A */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* B */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* C */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* D */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* E */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* F */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};


static char DIGIT_ARRAY[256] =
{
	//      0 1 2 3 4 5 6 7 8 9 A B C D E F
	/* 0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 2 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 3 */ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
	/* 4 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 7 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 8 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* 9 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* A */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* B */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* C */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* D */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* E */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	/* F */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

}//namespace _detail
}//namespace weakType
}//namespace wolv




#endif
